package com.wq.code;

/**
 * @Author: wangqiang20995
 * @Date:2019/4/23
 * @Description:内存泄露demo
 * @Resource:
 */
public class MemoryLeakDemo {

    static {
        i = 1;

        //下面这句会编译报错，定义在静态代码块之后的静态变量，只能赋值，不能访问
//        System.out.println(i);
    }

    static int i ;

    /**
     * bigData是一个大对象，内部类InnerClass为非静态，所以属于MemoryLeakDemo的实例对象
     * 在display方法中，有10次循环，每次都new了一个MemoryLeakDemo，所以每次都给bigData分配了5M左右的空间
     * 虽然在display的方法里面有leakDemo=null释放引用，但是byte[]数组的还是被内部类InnerClass使用，所以实际上bigData并没有被释放
     * 然后通过-Xms10m -Xmx10m设置最小堆和最大堆为10m，小于display方法的for循环创建的一共5*10=50M的内存大小
     * 由于之前的bigData的内存泄露，再加上最大堆的大小限制，所以会报java.lang.OutOfMemoryError: Java heap space
     */
    private byte[] bigData = new byte[1024 * 1024 * 5];

    public class InnerClass{

        byte[] copy;

        private void display() {
            for (int i = 0; i < 10; i++) {
                MemoryLeakDemo leakDemo = new MemoryLeakDemo();
                copy = leakDemo.bigData;
                leakDemo = null;
            }

//            list.forEach(aByte -> System.out.println(aByte.toString()));
        }
    }

    public static void main(String[] args){
        MemoryLeakDemo demo = new MemoryLeakDemo();
        InnerClass innerClass = demo.new InnerClass();

        innerClass.display();
        System.out.println("done");
    }
}
